package com.example.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.example.common.Result;
import com.example.common.enums.ResultCodeEnum;
import com.example.common.enums.RoleEnum;
import com.example.dto.EmailLoginDto;
import com.example.entity.Account;
import com.example.entity.Category;
import com.example.entity.Staff;
import com.example.exception.CustomException;
import com.example.service.AdminService;
import com.example.service.AssetsService;
import com.example.service.CategoryService;
import com.example.service.StaffService;
import com.example.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.swing.*;
import java.time.Duration;
import java.util.*;

/**
 * 基础前端接口
 */
@RestController
public class WebController {

    @Resource
    private AdminService adminService;
    @Resource
    private StaffService staffService;
    @Resource
    private CategoryService categoryService;
    @Resource
    private AssetsService assetsService;

    @Autowired
    private JavaMailSender sender;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Value("${spring.mail.username}")
    private String from;

    private static final String TEST_EMAIL = "437404601@qq.com";

    @GetMapping("/")
    public Result hello() {
        return Result.success("访问成功");
    }

    /**
     * 登录
     */
    @PostMapping("/login")
    public Result login(@RequestBody Staff staff) {
        if (ObjectUtil.isEmpty(staff.getUsername()) || ObjectUtil.isEmpty(staff.getPassword())
                || ObjectUtil.isEmpty(staff.getRole())) {
            return Result.error(ResultCodeEnum.PARAM_LOST_ERROR);
        }
        if (RoleEnum.ADMIN.name().equals(staff.getRole())) {
            staff = (Staff) adminService.login(staff);
        } else if (RoleEnum.STAFF.name().equals(staff.getRole())) {
            staff = staffService.login(staff);
        }
        return Result.success(staff);
    }

    @PostMapping("/sendCode")
    public Result sendCode(@RequestBody EmailLoginDto emailLoginDto) throws MessagingException {
        if (StrUtil.isBlank(emailLoginDto.getEmail())) {
            return Result.error(ResultCodeEnum.PARAM_LOST_ERROR);
        }
        Staff staff = staffService.selectAll(null).
                stream()
                .filter(stff -> stff.getEmail() != null)
                .filter(
                        stf -> stf.getEmail().equals(emailLoginDto.getEmail()))
                .findFirst()
                .orElse(null);
        if (staff == null) {
            return Result.error("500", "邮箱不存在");
        }
        //随机生成六位数验证码
        String code = RandomUtil.randomNumbers(6);
        String key = emailLoginDto.getEmail() + ":code";
        MimeMessage msg = sender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(msg, true, "UTF-8");
        helper.setFrom(from);
//        helper.setTo(emailLoginDto.getEmail());  //暂时用测试邮箱
        helper.setTo(TEST_EMAIL);
        helper.setSubject("【企业固定资产管理系统】");
        helper.setText("<html><body><h1>您好,邮箱快捷登录验证码：" + code + "</h1></body></html>", true);
        sender.send(helper.getMimeMessage());
        stringRedisTemplate.opsForValue().set(key, code, Duration.ofMinutes(1));
        return Result.success();
    }

    @PostMapping("/loginByEmail")
    public Result loginByEmail(@RequestBody EmailLoginDto emailLoginDto) {
        if (StrUtil.isBlank(emailLoginDto.getEmail()) || StrUtil.isBlank(emailLoginDto.getCode())) {
            return Result.error(ResultCodeEnum.PARAM_LOST_ERROR);
        }
        Staff staff = staffService.selectAll(null).
                stream()
                .filter(stff -> stff.getEmail() != null)
                .filter(
                        stf -> stf.getEmail().equals(emailLoginDto.getEmail()))
                .findFirst()
                .orElse(null);
        if (staff == null) {
            return Result.error("500", "邮箱不存在");
        }
        if (Objects.equals(stringRedisTemplate.opsForValue().get(emailLoginDto.getEmail() + ":code"), emailLoginDto.getCode())) {
            // 生成token
            String tokenData = staff.getId() + "-" + RoleEnum.STAFF.name();
            String token = TokenUtils.createToken(tokenData, staff.getPassword());
            staff.setToken(token);
            return Result.success(staff);
        }
        return Result.error("500", "验证码错误");
    }

    /**
     * 注册
     */
    @PostMapping("/register")
    public Result register(@RequestBody Staff staff) {
        if (StrUtil.isBlank(staff.getUsername()) || StrUtil.isBlank(staff.getPassword())
                || ObjectUtil.isEmpty(staff.getRole())) {
            return Result.error(ResultCodeEnum.PARAM_LOST_ERROR);
        }
        if (RoleEnum.STAFF.name().equals(staff.getRole())) {
            staffService.register(staff);
        } else {
            return Result.error("500", "只允许注册员工");
        }
        return Result.success();
    }


    /**
     * 修改密码
     */
    @PutMapping("/updatePassword")
    public Result updatePassword(@RequestBody Account account) {
        if (StrUtil.isBlank(account.getUsername()) || StrUtil.isBlank(account.getPassword())
                || ObjectUtil.isEmpty(account.getNewPassword())) {
            return Result.error(ResultCodeEnum.PARAM_LOST_ERROR);
        }
        if (RoleEnum.ADMIN.name().equals(account.getRole())) {
            adminService.updatePassword(account);
        } else if (RoleEnum.STAFF.name().equals(account.getRole())) {
            staffService.updatePassword(account);
        }
        return Result.success();
    }

    /**
     * 分类资产的数据统计
     */
    @GetMapping("/selectPie")
    public Result selectPie() {
        List<Category> categoryList = categoryService.selectAll(null);
        List<Map<String, Object>> list = new ArrayList<>();
        for (Category category : categoryList) {
            int count = assetsService.selectCountByCategory(category.getName());
            if (count == 0) {
                continue;
            }
            Map<String, Object> map = new HashMap<>();
            map.put("name", category.getName());
            map.put("value", count);
            list.add(map);
        }
        return Result.success(list);
    }

}
